// 获取worldstate

import { Autoplainning } from "Autoplanning/Autoplainning";
import { EntityManager } from "./EntityManager/EntityManager";
import { PollingStationManager } from "./PollingStation/PollingStationManager";
import { EventChecker } from "./EventChecker/CheckFunction/Room/EventChecker";
 
import { WhiteListManager } from "./EngineConfig/WhiteListManager";
import { PathFinderManager } from "GameLoop/Path/PathFinderManager";
import { StationNetwork } from "GameLoop/Path/StationNetwork";
import { TimerManager } from "./Timer/TimerManager";
import { CacheManager } from "cache/CacheManager";
import { GlobalEvent } from "./EventChecker/GlobalEvent";
import { RoomEvent } from "./EventChecker/RoomEvent";
 
/**
 * 提供注册事件的接口
 */
type RecordEvent<T extends TEventTypes>= Record<T,TCallback<T>[T]>;
/*@profile*/
export class WorldState 
{
    private nextNotifys:Record<EventRegion,Map<string,INotifyEvent>>={}    ; //事件通知
    private eventRecord:Record<EventRegion,RecordEvent<TEventTypes>>={};
    private _timer:TimerManager;
    /**********************属性*****************************************************************************************************/
    private entityManager:EntityManager;
    private station:PollingStationManager;

    private worldInit:Record<number,IEventChecker []>={}

    // 全局得
    // private tickStartCheck:Record<number,IEventChecker []>={}
    // private tickEndCheck:Record<number,IEventChecker []>={}
    private _globalEventCheck:GlobalEvent;
    private _roomEventCheck:RoomEvent;
 
    constructor()
    {
        this.entityManager = new EntityManager();
        global.world = new  PollingStationManager();
        global.heapcache =  {pos:{}};
        this._timer = new TimerManager();
        this.station =  global.world ;
        this._globalEventCheck = new GlobalEvent();
        this._roomEventCheck = new RoomEvent();
    }
    /**
     * 实体数据缓存
    */
    public get EntityManager()
    {
        return this.entityManager
    }
    public get EntityDB()
    {
        return this.entityManager.EntityDB;
    }

    public get Station()
    {
        return this.station;
    }
    
    public get Timer()
    {
        return this._timer;
    }

    /************************方法*********************************************************************/
    /**
     * 初始化
     */
    public init()
    {
        CacheManager.MemoryInit()
        global.commonMatrix = {}
   
        this.initEventChecker();
        // Autoplainning.Init();
        this._globalEventCheck.init(this,this.eventTriger.bind(this))
        this._roomEventCheck.init(this,this.eventTriger.bind(this))
        WhiteListManager.InitWhiteList();

        this.entityManager.init();
        this._timer.emitter = this.eventTriger.bind(this);
         // 初始化房间缓存
        for(let key in Game.rooms)
        {
            const room = Game.rooms[key];
            // this.Station.tryRegisterRoom(key);
            this.onWorldInit(room);
        }
       
        for(let k in Game.powerCreeps)
        {
            Game.powerCreeps[k].initAttributes();
        }
    }

    private initEventChecker()
    {
        this.nextNotifys={};
        this.worldInit ={
            1:[
                EventChecker.checkNewRoom,
                EventChecker.initRoomAttribute
            ]
        }
        this._globalEventCheck.initEvent();
        this._roomEventCheck.initEvent();
         
    }
    

    /**
     * 状态检测，事件分发
     */
    public tickStart()
    {
        // this.globalTickStart();
        global._move_intents = {};
        this._globalEventCheck.tickStart(this);
        for(let key in Game.rooms)
        {
            // this.onTickStart(Game.rooms[key]);
            this.Station.tryRegisterRoom(key);
            global._move_intents[key]={};
            if(Memory.Debug?.road)
            {
                const roads = StationNetwork.getInstance.PathCache.findRoomCache(key);
                roads.forEach(e=>
                {
                    Game.rooms[key].visual.text('r',e.x,e.y);
                })
            }
            // global._move_intents[key] = {};
           
            this._roomEventCheck.tickStart(Game.rooms[key]);
        }
        this.dispatchNotify();
        this._timer.tick();
    }
    public tickEnd()
    {
        this._globalEventCheck.tickEnd(this);
        for(let key in Game.rooms)
        {
            // this.onTickStart(Game.rooms[key]);
            this._roomEventCheck.tickEnd(Game.rooms[key]);
        }
      
    }
    // 注册监听事件
    public listenEvent<T extends TEventTypes> (type:T,callback:TCallback<T>[T],region:EventRegion=Game.shard.name)
    {
        if(!this.eventRecord[region])
        {
            this.eventRecord[region]={[type]:callback} as any;
        }
        else
        {
            this.eventRecord[region][type]=callback as any;
        }
    }
    /**
     * 取消房间的事件注册
     * @param region 
     */
    public unregisterEvent(region:EventRegion)
    {
        delete this.eventRecord[region];
    }

    /**
     * 整个workstate初始化的时候。主要是初始化主房。因为其他挖矿等信息都是挂在在主房之下
     * @param room 
     */
    private onWorldInit(room:Room)
    {
        this.station.tryRegisterRoom(room.name);

        if(this.worldInit[room.getType()])
        {
            for(const e of this.worldInit[room.getType()])
            {
                e(this,room as Required<Room>,this.eventTriger.bind(this));
            }
        }
    }
 

    /**
     * 根据挡箭感知的数据进行事件分发
     * */ 
    private eventTriger<T extends TEventTypes>(region:EventRegion,eventtype:T,param:IWorldEvents[T])
    {
         
        if(this.eventRecord[region] && this.eventRecord[region][eventtype])
        {
            this.eventRecord[region][eventtype](eventtype as never,param as any,region);
            
        }
        else
        {
            
            // 
            global.Log.Info(`没有对${region} 事件 ${ eventtype} 的  监听`);
        }
    }

    /**
     * 分发注册得事件消息
     */
    private dispatchNotify()
    {
        const _this = this;
        for(let k in this.nextNotifys)
        {
            this.nextNotifys[k].forEach(e=>
                {
                    // global.Log.Info(`region:${k} 下一帧的事件分发 ${JSON.stringify(e)}`);
                    _this.eventTriger(k,e.type,e)
                })
            this.nextNotifys[k].clear();
        }
    }

    
    /**
     * 注册事件消息
     */
    public registerNotify(region:EventRegion,eventtype:INotifyEvent)
    {
        const key = `${eventtype.region}-${eventtype.room}_${eventtype.type}`;
        // 这里没有去重复判断
        if(this.nextNotifys[region])
        {
            if(this.nextNotifys[region].has(key))
            {
                global.Log.Warning(`重复注册事件：${key}`);
            }
            else 
            {
                this.nextNotifys[region].set(key,eventtype);
            }
            
        }
        else
        {
            this.nextNotifys[region] = new Map<string,INotifyEvent>();
            this.nextNotifys[region].set(key,eventtype);
        }
    }

    
}